import os.path
import time,h5py
from threading import Thread
from PyQt5.QtWidgets import QWidget,QFileDialog,QAbstractItemView,QToolTip
from PyQt5.QtGui import QIntValidator,QDoubleValidator,QStandardItem,QStandardItemModel,QCursor
from PyQt5.QtCore import pyqtSignal,Qt,QTimer
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg,NavigationToolbar2QT
from matplotlib.figure import Figure
from keras.models import load_model
from gui.windows.analysisWin import Ui_analysisWindow
from config.method import *
from config.constant import *
from config.network import custom_comp
from data.h5_wr import get_analysis_data

class AnalysisWindow(QWidget, Ui_analysisWindow):

    signal_update_process_text = pyqtSignal(str,bool)
    signal_update_analysis_bar=pyqtSignal(float)
    signal_result_show=pyqtSignal()
    signal_result_save=pyqtSignal()

    def __init__(self,startWindow):
        super(AnalysisWindow, self).__init__()
        self.setupUi(self)
        self.setFixedSize(1391, 800)
        self.startWindow=startWindow
        self.param_dict=startWindow.param_dict
        self.initial_property()
        self.initial_widget()
        self.connect_slot()

    def initial_property(self):
        self.text_string = ''
        self.result_path_list=[]
        self.result_weight_list=[]
        self.figure = Figure()
        self.canvas = FigureCanvasQTAgg(self.figure)
        self.toolbar = NavigationToolbar2QT(self.canvas, self)
        self.vL_result_show.addWidget(self.canvas)
        self.hL_toolbar.addWidget(self.toolbar)
        attacker_class = type(self.param_dict['attack_method'] + "_class", (object,), {
            'attack': func_attack[self.param_dict['attack_method']],
            'get_guess_key': func_guess_key[self.param_dict['attack_method']],
            'get_rank': func_rank[self.param_dict['attack_method']],
            'param_dict': self.param_dict,
            'traces_attack': None,
            'midvalue_attack': None,
            'description_attack': None,
            'mkey': None,
            'rkey': None,
            'plaintext': None,
            'ciphertext': None,
            'target_bit':0,
            'weight_list':self.result_weight_list,
            'path_list':self.result_path_list
        })
        self.attacker = attacker_class()

    def initial_widget(self):
        self.attack_method.addItems(ATTACK_METHOD)
        self.network.addItems(NETWORK)
        self.epochs.setText(str(self.param_dict['epochs']))
        self.batch_size.setText(str(self.param_dict['batch_size']))
        self.learning_rate.setText(str(self.param_dict['learning_rate']))
        self.activation.addItems(['relu','selu','tanh','elu'])
        self.activation.setCurrentText(self.param_dict['activation'])
        self.target_byte.setMaximum(get_mkey_bytes[self.param_dict["target_algorithm"]] - 1)
        if self.param_dict["target_byte"]==-1:
            self.target_byte.setSpecialValueText('All')
        else:
            self.target_byte.setValue(self.param_dict["target_byte"])
        self.target_bit.setValue(0)
        self.traces_steps.setText(str(self.param_dict["attack_steps"]))
        self.analysis_bar.setMaximum(100)
        self.analysis_bar.setValue(0)
        self.analysis_bar.hide()
        self.result_path_view.horizontalHeader().setFixedHeight(30)
        self.result_path_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.result_path_model = QStandardItemModel(0, 2)
        self.result_path_model.setHorizontalHeaderLabels(['路径', '权重'])
        self.result_path_view.setModel(self.result_path_model)
        self.result_path_view.setColumnWidth(0,280)
        with open("resource/style.qss", encoding='UTF-8') as f:
            self.setStyleSheet(f.read())
        self.set_validator()

    def connect_slot(self):
        self.attack_method.currentTextChanged.connect(self.set_attack_method)
        self.start_analysis.clicked.connect(self.start_analysis_process)
        self.clear_related_info.clicked.connect(lambda :self.update_text('#'))
        self.target_byte.valueChanged.connect(self.set_target_byte)
        self.target_bit.valueChanged.connect(self.set_target_bit)
        self.result_path_view.doubleClicked.connect(self.modify_result_path)
        self.result_path_view.clicked.connect(self.get_item_tip)
        self.add_item.clicked.connect(self.add_result_item)
        self.remove_item.clicked.connect(self.remove_result_item)
        self.result_path_model.itemChanged.connect(self.item_check)
        self.analysis_path_browse.clicked.connect(self.browse_analysis_path)
        self.model_path_browse.clicked.connect(self.browse_model_path)
        self.stop_analysis.clicked.connect(self.set_stop_analysis)
        self.view_dataset_info.clicked.connect(self.viewing_dataset_info)
        self.related_info.textChanged.connect(lambda: self.related_info.moveCursor(11))
        self.signal_update_process_text.connect(self.update_process_text)
        self.signal_update_analysis_bar.connect(self.update_analysis_bar)
        self.signal_result_show.connect(self.result_show)
        self.signal_result_save.connect(self.result_save)

    def get_item_tip(self):
        column = self.result_path_view.currentIndex().column()
        if column==0:
            path = self.result_path_view.currentIndex().data()
            QToolTip.showText(QCursor.pos(), path)

    def modify_result_path(self):
        row = self.result_path_view.currentIndex().row()
        column = self.result_path_view.currentIndex().column()
        if column==0:
            fname = QFileDialog.getOpenFileName(self, "Open File", self.param_dict['result_file_dir'], "*.txt")
            if fname[0]:
                self.result_path_model.item(row,column).setText(fname[0])
                self.result_path_list[row]=fname[0]

    def add_result_item(self):
        row_num = self.result_path_model.rowCount()
        self.result_path_list.append('未设置')
        item_path=QStandardItem('未设置')
        item_path.setEditable(False)
        self.result_path_model.setItem(row_num, 0, item_path)
        self.result_weight_list.append(0.0)
        item_weight=QStandardItem('0.0')
        item_weight.setEditable(True)
        item_weight.setTextAlignment(Qt.AlignHCenter|Qt.AlignCenter)
        self.result_path_model.setItem(row_num,1,item_weight)

    def remove_result_item(self):
        row = self.result_path_view.currentIndex().row()
        if row==-1:
            return
        del self.result_weight_list[row]
        del self.result_path_list[row]
        self.result_path_model.removeRow(row)

    def item_check(self,item):
        if item.column()==1:
            try:
                value=float(item.text())
                if value<0 or value>1:
                    raise ValueError(f"请输入正确大小的权重！(0-1)")
                self.result_weight_list[item.row()]=value
            except Exception as e:
                self.update_text(repr(e),False)
                item.setText(str(self.result_weight_list[item.row()]))

    def set_validator(self):
        int_validator1 = QIntValidator(10, 999, self)
        int_validator2 = QIntValidator(0, 9999, self)
        double_validator=QDoubleValidator(0,1,6,self)
        double_validator.setNotation(QDoubleValidator.StandardNotation)
        self.epochs.setValidator(int_validator1)
        self.batch_size.setValidator(int_validator1)
        self.traces_steps.setValidator(int_validator2)
        self.learning_rate.setValidator(double_validator)

    def fresh_param(self):
        self.param_dict["network"]=self.network.currentText()
        self.param_dict["epochs"]=int(self.epochs.text())
        self.param_dict["batch_size"]=int(self.batch_size.text())
        self.param_dict["learning_rate"]=float(self.learning_rate.text())
        self.param_dict["activation"]=self.activation.currentText()

    def set_attacker_random_index(self):
        shuffle_indexes = np.random.permutation(self.attacker.traces_attack.shape[0])
        self.attacker.traces_attack=self.attacker.traces_attack[shuffle_indexes]
        self.attacker.midvalue_attack=self.attacker.midvalue_attack[shuffle_indexes]
        if self.attacker.mkey is not None and self.attacker.mkey.shape[0]>1:
            self.attacker.mkey=self.attacker.mkey[shuffle_indexes]
        if self.attacker.rkey is not None and not isinstance(self.attacker.rkey,int) and self.attacker.rkey.shape[0]>1:
            self.attacker.rkey=self.attacker.rkey[shuffle_indexes]
        if self.attacker.plaintext is not None and self.attacker.plaintext.shape[0]>1:
            self.attacker.plaintext=self.attacker.plaintext[shuffle_indexes]
        if self.attacker.ciphertext is not None and self.attacker.ciphertext.shape[0]>1:
            self.attacker.ciphertext=self.attacker.ciphertext[shuffle_indexes]

    def start_analysis_th(self):
        self.prob=[]
        self.prob_list=[]
        self.index=[]
        self.key_rank=[]
        self.guess_key=[]
        try:
            if self.param_dict["target_byte"] != -1:
                self.signal_update_process_text.emit("开始分析...", False)
            gen=self.attacker.attack()
            if self.param_dict["attack_method"]=='COMB':
                index_max=next(gen)
            else:
                # self.set_attacker_random_index()
                index_max=self.attacker.traces_attack.shape[0]
            while True:
                self.continue_analysis = False
                prob,index=next(gen)
                self.prob=prob
                self.prob_list.append(prob)
                self.index.append(index)
                self.guess_key.append(self.attacker.get_guess_key(prob))
                if self.attacker.rkey is not None:
                    if isinstance(self.attacker.rkey,int):
                        self.key_rank.append(self.attacker.get_rank(prob,self.attacker.rkey))
                    else:
                        if self.param_dict["target_byte"]==-1:
                            self.key_rank.append(self.attacker.get_rank(prob, self.attacker.rkey[0, self.temp_byte]))
                        else:
                            self.key_rank.append(self.attacker.get_rank(prob,self.attacker.rkey[0,self.param_dict["target_byte"]]))
                self.signal_update_analysis_bar.emit(100*index/index_max)
                self.signal_result_show.emit()
                while self.continue_analysis is False:
                    time.sleep(0.1)
                if self.param_dict["target_byte"]==-1 and len(self.key_rank)>5 and sum(self.key_rank[-5:])==0:
                    gen.close()
                    raise StopIteration
                if self.stop_cur_analysis is True:
                    gen.close()
                    raise StopIteration
        except StopIteration:
            self.signal_update_analysis_bar.emit(100)
            if self.param_dict["target_byte"]==-1:
                if len(self.key_rank) > 5 and sum(self.key_rank[-5:]) == 0:
                    self.signal_update_process_text.emit(f"第{self.temp_byte}字节攻击成功.", False)
                else:
                    self.signal_update_process_text.emit(f"第{self.temp_byte}字节攻击失败！", False)
                if self.temp_byte==15:
                    self.signal_update_process_text.emit("分析完毕.", True)
            else:
                self.signal_result_save.emit()
                self.signal_update_process_text.emit("分析完毕.",True)
        # except Exception as e:
        #     self.signal_update_process_text.emit(repr(e),False)
        #     self.signal_update_process_text.emit("分析失败！",True)

    def analysis_all(self):
        model_file_path = [self.model_dir + '/' + file for file in os.listdir(self.model_dir) if file.endswith(".h5")]
        analysis_file_path = [self.analysis_dir + '/' + file for file in os.listdir(self.analysis_dir) if file.endswith(".h5")]
        model_file_path_sort = [0] * 16
        analysis_file_path_sort = [0] * 16
        for i in range(16):
            index = int(os.path.basename(model_file_path[i]).split("_")[4][4:])
            model_file_path_sort[index] = model_file_path[i]
            index = int(os.path.basename(analysis_file_path[i]).split("_")[3][4:])
            analysis_file_path_sort[index] = analysis_file_path[i]
        for i in range(16):
            if hasattr(self, 'th_analysis'):
                while self.th_analysis.is_alive():
                    time.sleep(0.1)
            if self.stop_cur_analysis is True:
                self.signal_update_process_text.emit("停止分析.", True)
                break
            self.temp_byte = i
            self.attacker.model = load_model(model_file_path_sort[i], custom_objects=custom_comp)
            aa=analysis_file_path_sort[i]
            traces, midvalue, metadata, description = get_analysis_data(aa)
            self.attacker.traces_attack = traces
            self.attacker.midvalue_attack = midvalue
            self.attacker.description_attack = description
            if "mkey" in metadata:
                mkey = metadata["mkey"]
                self.attacker.mkey = mkey.reshape(-1, mkey.shape[len(mkey.shape) - 1])
            else:
                self.attacker.mkey = None
            if "rkey" in metadata:
                self.attacker.rkey = metadata["rkey"]
            else:
                self.attacker.rkey = None
            if "plaintext" in metadata:
                self.attacker.plaintext = metadata["plaintext"]
            else:
                self.attacker.plaintext = None
            if "ciphertext" in metadata:
                self.attacker.ciphertext = metadata["ciphertext"]
            else:
                self.attacker.ciphertext = None
            self.th_analysis = Thread(target=self.start_analysis_th)
            self.th_analysis.start()


    def start_analysis_process(self):
        if self.param_dict["attack_method"]!='COMB' and self.attacker.traces_attack is None:
            self.update_text("请先加载数据！", False)
            return
        if self.param_dict['attack_method'] == 'DDLSCA':
            self.fresh_param()
        self.start_analysis.setEnabled(False)
        self.attack_method.setEnabled(False)
        self.analysis_bar.show()
        self.stop_cur_analysis = False
        steps=int(self.traces_steps.text())
        if self.param_dict['attack_method'] == 'DDLSCA':
            steps_max=max(1,int(self.param_dict['epochs']/4))
            if steps==0 or steps>steps_max:
                self.signal_update_process_text.emit(f"请输入合适的单步分析步长: [1, {steps_max}]！",True)
                return
        elif self.param_dict["attack_method"]!='COMB':
            steps_max = max(1,int(self.attacker.traces_attack.shape[0] / 4))
            if steps==0 or steps>steps_max:
                self.signal_update_process_text.emit(f"请输入合适的单步分析步长: [1, {steps_max}]！",True)
                return
        self.param_dict["attack_steps"]=steps
        if self.param_dict["target_byte"]==-1:
            self.model_dir = os.path.dirname(self.model_path.text())
            self.analysis_dir = os.path.dirname(self.analysis_path.text())
            th_analysis = Thread(target=self.analysis_all)
            th_analysis.start()
        else:
            th_analysis = Thread(target=self.start_analysis_th)
            th_analysis.start()

    def result_show(self):
        self.figure.clear()
        ax1 = self.figure.add_subplot(211)
        ax1.set_ylabel('猜测密钥值')
        if self.param_dict['attack_method']=='DDLSCA':
            ax1.set_xlabel('迭代次数')
        else:
            ax1.set_xlabel('能量迹条数')
        guess_key, = ax1.plot(self.index, self.guess_key, color='g')
        if len(self.key_rank) > 0:
            ax1.set_title('猜测密钥和密钥排名')
            key_rank, = ax1.plot(self.index, self.key_rank, color='r')
        else:
            ax1.set_title('猜测密钥')
            key_rank=None
        ax2 = self.figure.add_subplot(212)
        ax2.set_ylabel('区分函数值')
        ax2.set_xlabel('猜测密钥值')
        prob, = ax2.plot(self.prob, color='b')
        if len(self.key_rank) > 0:
            if self.param_dict['attack_method'] == 'COMB':
                rkey_byte=self.attacker.real_key
            else:
                if isinstance(self.attacker.rkey,int):
                    rkey_byte = self.attacker.rkey
                else:
                    if self.param_dict["target_byte"]==-1:
                        rkey_byte = self.attacker.rkey[0, self.temp_byte]
                    else:
                        rkey_byte = self.attacker.rkey[0, self.param_dict["target_byte"]]
            ax2.scatter(rkey_byte, self.prob[rkey_byte], s=40, color='r')
            self.figure.legend([key_rank, guess_key,prob], ["密钥排名", "猜测密钥","区分函数值"])
        else:
            self.figure.legend([guess_key,prob], ["猜测密钥","区分函数值"])
        self.canvas.draw()
        self.continue_analysis=True

    def result_save(self):
        ctime = time.localtime()
        dir = self.param_dict['result_file_dir'] + f"{ctime.tm_year}-{ctime.tm_mon}-{ctime.tm_mday}/"
        hms = f'{ctime.tm_hour:02d}{ctime.tm_min:02d}{ctime.tm_sec:02d}'
        description = eval(self.attacker.description_attack)
        if self.autosave_result.isChecked():
            if os.path.exists(dir) is False:
                os.makedirs(dir)
            if description is None:
                file_name = f"{self.param_dict['attack_method']}_byte{self.param_dict['target_byte']}_{hms}.txt"
            else:file_name = f"{self.param_dict['attack_method']}_{description['target_algorithm']}_{description['leakage_model']}_byte{self.param_dict['target_byte']}_{hms}.txt"
            with open(dir + file_name, "w") as f:
                data = f"analysis time: {ctime.tm_year}-{ctime.tm_mon}-{ctime.tm_mday} {ctime.tm_hour:02d}:{ctime.tm_min:02d}:{ctime.tm_sec:02d}\n"
                data += f"attack method: {self.param_dict['attack_method']}\n"
                if description is not None:
                    data += f"target algorithm: {self.param_dict['target_algorithm']}\n"
                    data += f"leakage model: {self.param_dict['leakage_model']}\n"
                    data += f"target byte: {self.param_dict['target_byte']}\n"
                    if self.param_dict['attack_method'] in ATTACK_METHOD_NONPROFILE and len(self.attacker.midvalue_attack.shape)==3:
                        if self.attacker.target_bit is None:
                            data += "target bit: all\n"
                        else:
                            data += f"target bit: {self.attacker.target_bit}\n"
                if len(self.key_rank)>0:
                    if isinstance(self.attacker.rkey, int):
                        data += f"real round key byte: {self.attacker.rkey}\n"
                    else:
                        data += f"real round key byte: {self.attacker.rkey[0, self.param_dict['target_byte']]}\n"
                    data += f"key rank: {self.key_rank[-1]}\n"
                    data += f"key rank list: {self.key_rank}\n"
                data += f"guess key: {self.guess_key[-1]}\n"
                data += f"guess key list: {self.guess_key}\n"
                data += f"probability: {self.prob_list}\n"
                data += f"index: {self.index}\n"
                f.write(data)
                self.update_text("分析结果数据已保存.", False)
        if self.autosave_figure.isChecked():
            if os.path.exists(dir) is False:
                os.makedirs(dir)
            if description is None:
                file_name = f"{self.param_dict['attack_method']}__byte{self.param_dict['target_byte']}_{hms}.{self.param_dict['figure_format']}"
            else:file_name = f"{self.param_dict['attack_method']}_{description['target_algorithm']}_{description['leakage_model']}_byte{self.param_dict['target_byte']}_{hms}.{self.param_dict['figure_format']}"
            fig_save_path = dir + file_name
            self.figure.savefig(fig_save_path, dpi=self.param_dict["figure_dpi"])
            self.update_text("分析结果图片已保存.", False)

    def update_process_text(self,text,finish):
        self.update_text(text,False)
        if finish:
            self.stop_cur_analysis=False
            self.start_analysis.setEnabled(True)
            self.attack_method.setEnabled(True)
            self.analysis_bar.setValue(0)
            self.analysis_bar.hide()

    def update_text(self, data, override=True):
        if override:
            self.text_string = ''
        if type(data) is dict:
            self.related_info.setStyleSheet("color:black;")
            self.text_string += 'trs file head:\n'
            for k in data:
                self.text_string += f"  {k}: {data[k]}\n"
            self.text_string += '\n'
        else:
            if len(data)==0:
                pass
            elif data[-1] == '#':
                self.text_string += str(data)[:-1]
            elif len(data)>3 and data[-3:]=='...':
                self.text_string += "(Please Wait)" + str(data) + '\n'
            elif data[-1]=='.':
                self.text_string += "(Execution Success)"+str(data) + '\n'
            elif data[-1]=='!' or data[-1]=='！':
                self.text_string += "(Execution Fail)" + str(data) + '\n'
            else:
                self.text_string += str(data) + '\n'
        self.related_info.setText(self.text_string)
        if len(self.text_string) > 10240:
            self.text_string = self.text_string[7680:]

    def viewing_dataset_info(self):
        fname = QFileDialog.getOpenFileName(self, "Open file", self.param_dict['analysis_file_dir'], "*.h5")
        if fname[0]:
            dataset_file = h5py.File(fname[0], "r")
            description = dataset_file['description'][0].decode('utf-8')
            description = description.replace(',', '\n').replace(',', '\n').replace('{', '{\n').replace('}', '\n}')
            self.update_text(f"数据集信息：\n{description}", False)

    def browse_analysis_path(self):
        try:
            fname = QFileDialog.getOpenFileName(self, "Open file", self.param_dict['analysis_file_dir'], "*.h5")
            if fname[0]:
                traces, midvalue, metadata,description=get_analysis_data(fname[0])
                self.attacker.traces_attack=traces
                self.attacker.midvalue_attack=midvalue
                self.attacker.description_attack=description
                description = description.replace(',', '\n').replace(',','\n').replace('{','{\n').replace('}','\n}')
                self.update_text(f"数据集信息：\n{description}", False)
                if "mkey" in metadata:
                    mkey=metadata["mkey"]
                    self.attacker.mkey=mkey.reshape(-1,mkey.shape[len(mkey.shape)-1])
                else:
                    self.attacker.mkey =None
                if "rkey" in metadata:
                    self.attacker.rkey=metadata["rkey"]
                    if len(self.attacker.rkey.shape)==0:
                        self.attacker.rkey=int(self.attacker.rkey)
                else:
                    self.attacker.rkey =None
                if "plaintext" in metadata:
                    self.attacker.plaintext=metadata["plaintext"]
                else:
                    self.attacker.plaintext =None
                if "ciphertext" in metadata:
                    self.attacker.ciphertext=metadata["ciphertext"]
                else:
                    self.attacker.ciphertext=None
                self.analysis_path.setText(fname[0])
                if len(self.attacker.midvalue_attack.shape)==3:
                    self.target_bit.setValue(0)
                    self.attacker.target_bit=0
                    self.target_bit.setMaximum(self.attacker.midvalue_attack.shape[2]-1)
                self.set_attack_method(self.param_dict["attack_method"])
        except Exception as e:
            self.update_text(repr(e),False)
            self.update_text("加载分析数据集失败！",False)

    def browse_model_path(self):
        try:
            fname = QFileDialog.getOpenFileName(self, "Open file", self.param_dict['model_file_dir'], "*.h5")
            if fname[0]:
                self.model_path.setText(fname[0])
                if self.param_dict['attack_method']=='DLSCA':
                    self.attacker.model=load_model(fname[0],custom_objects=custom_comp)
                if self.param_dict['attack_method'] == 'TA':
                    template_file=h5py.File(fname[0], "r")
                    self.attacker.template=np.array(template_file['template'])
        except Exception as e:
            self.update_text(repr(e),False)
            if self.param_dict['attack_method'] == 'TA':
                self.update_text("加载模板失败(可能选择了错误的文件)！",False)
            elif self.param_dict['attack_method'] == 'DLSCA':
                self.update_text("加载模型失败(可能选择了错误的文件)！", False)

    def update_analysis_bar(self,value):
        self.analysis_bar.setValue(value)

    def set_target_byte(self,target_byte):
        self.param_dict["target_byte"] = target_byte
        self.attacker.target_byte=target_byte
        if target_byte==-1:
            self.target_byte.setSpecialValueText('All')

    def set_target_bit(self,target_bit):
        self.attacker.target_bit=target_bit
        if target_bit==-1:
            self.attacker.target_bit=None
            self.target_bit.setSpecialValueText('All')

    def set_stop_analysis(self):
        self.stop_cur_analysis=True

    def reset_attacker(self,method):
        attacker_class = type(method + "_class", (object,), {
            'attack': func_attack[method],
            'get_guess_key': func_guess_key[method],
            'get_rank': func_rank[method],
            'param_dict': self.param_dict,
            'traces_attack': self.attacker.traces_attack,
            'midvalue_attack': self.attacker.midvalue_attack,
            'description_attack':self.attacker.description_attack,
            'mkey': self.attacker.mkey,
            'rkey': self.attacker.rkey,
            'plaintext': self.attacker.plaintext,
            'ciphertext': self.attacker.ciphertext,
            'target_bit':self.attacker.target_bit,
            'weight_list':self.result_weight_list,
            'path_list':self.result_path_list
        })
        self.attacker = attacker_class()

    def set_attack_method(self,method):
        if self.param_dict["attack_method"]!=method:
            self.reset_attacker(method)
        self.param_dict["attack_method"] = method
        switch_hide1 = method in ATTACK_METHOD_NONPROFILE
        switch_hide2 = method != "DDLSCA"
        switch_hide3 = switch_hide1 is False or self.attacker.midvalue_attack is None or len(self.attacker.midvalue_attack.shape)!=3
        switch_hide4 = method != "COMB"
        switch_hide5 = method == "COMB"
        self.model_path_L.setHidden(switch_hide1 or switch_hide5)
        self.model_path.setHidden(switch_hide1 or switch_hide5)
        self.model_path_browse.setHidden(switch_hide1 or switch_hide5)
        self.network_L.setHidden(switch_hide2)
        self.network.setHidden(switch_hide2)
        self.epochs_L.setHidden(switch_hide2)
        self.epochs.setHidden(switch_hide2)
        self.batch_size_L.setHidden(switch_hide2)
        self.batch_size.setHidden(switch_hide2)
        self.learning_rate_L.setHidden(switch_hide2)
        self.learning_rate.setHidden(switch_hide2)
        self.activation_L.setHidden(switch_hide2)
        self.activation.setHidden(switch_hide2)
        self.target_bit_L.setHidden(switch_hide3 or switch_hide5)
        self.target_bit.setHidden(switch_hide3 or switch_hide5)
        self.result_path_view.setHidden(switch_hide4)
        self.result_file_path_L.setHidden(switch_hide4)
        self.add_item.setHidden(switch_hide4)
        self.remove_item.setHidden(switch_hide4)
        self.analysis_path.setHidden(switch_hide5)
        self.analysis_path_L.setHidden(switch_hide5)
        self.analysis_path_browse.setHidden(switch_hide5)
        self.traces_steps.setHidden(switch_hide5)
        self.traces_steps_L.setHidden(switch_hide5)
        if method=='TA':
            self.model_path_L.setText("模板路径")
        elif method=="DDLSCA":
            self.model_path_L.setText("模型路径")

    def showEvent(self, a0):
        self.attack_method.setCurrentText(self.param_dict["attack_method"])
        self.target_byte.setMaximum(get_mkey_bytes[self.param_dict["target_algorithm"]] - 1)
        self.target_byte.setValue(self.param_dict["target_byte"])
        self.set_attack_method(self.param_dict['attack_method'])

    def closeEvent(self, a0):
        self.text_string = ''
        self.signal_update_process_text.emit("", True)
        self.update_text("#", True)
        self.startWindow.fresh()
        self.startWindow.show()